#include "global.h"
#include "device.h"
#include "modbus.h"
#include "speed_cntr.h"
#include <setjmp.h>

jmp_buf main_loop_env;

void Main_Loop()
{
    LED = !LED;

    // update watch dog
    Update_WatchDog();

    Update_IO();

#ifdef ENABLE_REF_SPEED
    Update_Ref_Speed();
#endif

    // 一帧消息接收完成
    if (uart0_rx_pending && Uart0_FrameEnded() || uart0_delay_process)
    {
        uart0_rx_pending = 0;
        REN0 = 0;               // 禁止接收
        Process_Request();
    }

    // 应答结束, 允许接收
    if (!REN0 && !uart0_tx_pending && !uart0_delay_process)
    {
        uart0_len = 0;
        uart0_rx_pending = 0;
        REN0 = 1;
    }

#if (PCB_VERSION == PCB_A2)
    if (srd_m.need_cleanup && srd_m.cleanup)
        srd_m.cleanup();
#endif
    if (srd_y.need_cleanup && srd_y.cleanup)
        srd_y.cleanup();
    if (srd_z.need_cleanup && srd_z.cleanup)
        srd_z.cleanup();
}

void Process_Main_Loop()
{
    Main_Loop();

    if (pending_action)
        longjmp(main_loop_env, 1);
}

void main()
{
    Init_Device();

    // 如果不是软件复位, 清除事件记录
    if (!(RSTSRC & 0x10))
        event_count = 0;

    // 记录复位事件
    Log_Event(EVENT_RESET_PORT);

    // 保存上下文, 以便从Process_Main_Loop中直接跳转到此
    setjmp(main_loop_env);

    while(1)
    {
        Main_Loop();

        // 处理动作
        if (pending_action)
        {
            pending_action = 0;
            Process_Action();
        }
    }
}
